/*
 * (#)MyAccessDecisionManager.java 1.0 2010-6-23  
 */
package com.huaxingbankas.core.base.spring.security;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.Collection;
import java.util.Iterator;

import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Service;

/**
 * @author 璧靛�
 * @version $1.0, 2010-6-23
 * @since JDK6
 */
@Service("myAccessDecisionManagerBean")
public class MyAccessDecisionManager implements AccessDecisionManager
{
	/**
	 * Logger for this class
	 */
	private static final Log	logger	= LogFactory.getLog(MyAccessDecisionManager.class);

	// In this method, need to compare authentication with configAttributes.
	// 1, A object is a URL, a filter was find permission configuration by this URL, and pass to here.
	// 2, Check authentication has attribute in permission configuration (configAttributes)
	// 3, If not match corresponding authentication, throw a AccessDeniedException.
	/* 濡��涓���ㄥ�璇ヨ�婧��瀹��锛���ユ�琛�����锛������版�纭��瑙��锛��璁や负�ユ����锛�苟�捐�锛����hrow new AccessDeniedException("no right");杩��锛�氨浼���ヤ��㈡��扮�403.jsp椤甸�
	 * @see org.springframework.security.access.AccessDecisionManager#decide(org.springframework.security.core.Authentication, java.lang.Object, java.util.Collection)
	 */
	public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException,
			InsufficientAuthenticationException
	{
		if (logger.isDebugEnabled())
		{
			logger.debug("decide(Authentication, Object, Collection<ConfigAttribute>) - start");
		}

		if (configAttributes == null)
		{
			if (logger.isDebugEnabled())
			{
				logger.debug("the url="+object.toString()+" is no control!");
				logger.debug("decide(Authentication, Object, Collection<ConfigAttribute>) - end");
			}
			return;
		}
		
		Iterator<ConfigAttribute> ite = configAttributes.iterator();
		while (ite.hasNext())
		{
			ConfigAttribute ca = ite.next();
			String needRole = ((SecurityConfig) ca).getAttribute();
			for (GrantedAuthority ga : authentication.getAuthorities())
			{
				if (needRole.equals(ga.getAuthority()))
				{ // ga is user's role.

					if (logger.isDebugEnabled())
					{
						logger.debug("decide(Authentication, Object, Collection<ConfigAttribute>) - end");
					}
					return;
				}
			}
		}
		throw new AccessDeniedException("no right");
	}

	@Override
	public boolean supports(ConfigAttribute attribute)
	{
		if (logger.isDebugEnabled())
		{
			logger.debug("supports(ConfigAttribute) - start");
		}

		if (logger.isDebugEnabled())
		{
			logger.debug("supports(ConfigAttribute) - end");
		}
		return true;
	}

	@Override
	public boolean supports(Class<?> clazz)
	{
		if (logger.isDebugEnabled())
		{
			logger.debug("supports(Class<?>) - start");
		}

		if (logger.isDebugEnabled())
		{
			logger.debug("supports(Class<?>) - end");
		}
		return true;
	}

}
